package com.ml4ai.core.stack.redis;

import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisShardInfo;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by leecheng on 2018/11/24.
 */
@Setter
@Getter
public class RedisAgent {

    private String host;
    private Integer port = 3306;
    private Integer database = 0;
    private String password;
    private Jedis jedis;

    private JedisShardInfo jedisShardInfo;

    private List<HostAndPort> hostAndPorts;
    JedisCluster jedisCluster;

    private RedisAgent() {
    }

    private void init() {
        if (StringUtils.isNotEmpty(host)) {
            if (jedisShardInfo == null) {
                jedisShardInfo = new JedisShardInfo(host, port);
                if (StringUtils.isNotEmpty(password)) {
                    jedisShardInfo.setPassword(password);
                }
            }
            jedis = new Jedis(jedisShardInfo);
            if (database != null) {
                jedis.select(database);
            }
        }
    }

    private void initJedisCluster() {
        if (hostAndPorts != null && !hostAndPorts.isEmpty()) {
            jedisCluster = new JedisCluster(hostAndPorts.stream().collect(Collectors.toSet()));
        }
    }

    public Jedis getJedis() {
        if (jedis == null || !jedis.isConnected()) {
            init();
        }
        return jedis;
    }

    public JedisCluster getJedisCluster() {
        if (jedisCluster == null) {
            initJedisCluster();
        }
        return jedisCluster;
    }

    public static Builder builder() {
        return new Builder();
    }

    public static class Builder {

        private String host;
        private Integer port = 3306;
        private Integer database = 0;
        private String password;
        private List<HostAndPort> hostAndPorts;

        private Builder() {
        }

        public Builder host(String host) {
            this.host = host;
            return this;
        }

        public Builder port(Integer port) {
            this.port = port;
            return this;
        }

        public Builder database(Integer database) {
            this.database = database;
            return this;
        }

        public Builder password(String password) {
            this.password = password;
            return this;
        }

        public Builder add(String host, Integer port) {
            if (hostAndPorts == null) {
                hostAndPorts = new ArrayList<>();
            }
            hostAndPorts.add(new HostAndPort(host, port));
            return this;
        }

        public RedisAgent build() {
            RedisAgent agent = new RedisAgent();
            agent.setDatabase(database);
            agent.setHost(host);
            agent.setPort(port);
            agent.setPassword(password);
            agent.setHostAndPorts(hostAndPorts);
            return agent;
        }

    }

}
